#include "Buddy.h"
#include <wx/file.h>
#include "../core/Impp.h"


namespace Impp {

Buddy::Buddy(db_id id, db_id accountId, const  wxString & screenName2, const  wxString & customName2, Group* group, const int & flags) :
	id(id),
	accountId(accountId),
	screenName(screenName2),
	customName(customName2),
	status(UNKNOWN),
	group(group),
	protData(NULL),
	statusMsg(wxEmptyString),
	flags(flags)
{
	group->addBuddy(this);
}

Buddy::~Buddy()
{
	wxDELETE(protData);
}

db_id Buddy::getId() const{
	return id;
}

db_id Buddy::getAccountId() const{
	return accountId;
}

wxString Buddy::getName() const{
	if(!customName.IsEmpty()){
		return customName;
	}
	return screenName;
}

wxString Buddy::getScreenName() const{
	return screenName;
}

wxString Buddy::getCustomName() const{
	return customName;
}

void Buddy::setScreenName(const wxString & screenName){
	this->screenName=screenName;
}

void Buddy::setCustomName(const wxString & customName){
	this->customName=customName;
}

void Buddy::setStatus(const Status & status){
	if(protData!=NULL && (this->status!=OFFLINE && this->status!=UNKNOWN) &&  status==OFFLINE || status==UNKNOWN){
		protData->goesOffline();
	}
	this->status=status;
}

Status Buddy::getStatus() const{
	return status;
}

Group* Buddy::getGroup() const{
	if(group){
		return group;
	}else{
		wxLogFatalError(wxT("Buddy::getGroup: '%s' Group is null!"),screenName.c_str());
	}
	return NULL;
}

void Buddy::setGroup(Group* group){
	this->group=group;
}

iProtocolData* Buddy::getProtocolData(){
	return protData;
}

void Buddy::setProtocolData(iProtocolData* data){
	if(!this->protData){
		delete this->protData;
	}
	this->protData = data;
}

bool Buddy::setAvatar(wxString file){

	if(file.IsEmpty()){
		wxLogDebug(wxT("Buddy::setAvatar: file-string is empty"));
		return false;
	}

	if(!wxFile::Exists(file)){
		wxLogDebug(wxT("Buddy::setAvatar: Avatar-file doent exsist"));
		return false;
	}

	wxBitmap newavatar = wxBitmap(file,wxBITMAP_TYPE_ANY);

	if(!newavatar.Ok()){ //Bitmap error
		wxString n = getName();
		wxLogError(wxT("Buddy::setAvatar: Error setting Avatar for %s, not an valid bitmap"), n.c_str());
		return false;
	}
	avatar=newavatar;
	return true;
}

wxBitmap Buddy::getAvatar(){
	return avatar;
}

void Buddy::setStatusMsg(const wxString & statusMsg){
	wxLogTrace(wxT("AWAY"),wxT("%s statusmessage is now: %s"),getName().c_str(), statusMsg.c_str());
	this->statusMsg=statusMsg;
}

wxString Buddy::getStatusMsg() const{
	return statusMsg;
}

BuddyPriority Buddy::getPriority() const{
	if((flags & BUDDY_FLAG_PRIORITY_LOW) != 0){
		return BUDDY_PRIORITY_LOW;
	}
	if((flags & BUDDY_FLAG_PRIORITY_HIGH) != 0){
		return BUDDY_PRIORITY_HIGH;
	}
	return BUDDY_PRIORITY_NORMAL;
}

bool Buddy::isOnPrivacyList(BuddyPrivacyList list) const{
	switch(list){
		case BUDDY_PRIVACY_VISIBLELIST:
			return (flags & BUDDY_FLAG_VISISBLELIST) != 0;
		case BUDDY_PRIVACY_INVISIBLELIST:
			return (flags & BUDDY_FLAG_INVISIBLELIST) != 0;
		case BUDDY_PRIVACY_IGNORED:
			return (flags & BUDDY_FLAG_IGNORED) != 0;
		default:
			wxLogDebug(wxT("Buddy::isOnPrivacyList: illegal argument"));
			return false;
	}
}
bool Buddy::hasUnredMsg() const{
	return (flags & BUDDY_FLAG_UNREAD_MSG) != 0;
}
bool Buddy::hasAuthorisation() const{
	return (flags & BUDDY_FLAG_NO_AUTHORIZATION) == 0;
}
bool Buddy::isInBuddyList() const{
	return (flags & BUDDY_FLAG_NOT_INLIST) == 0;
}

bool Buddy::isSelf() const{
	return (flags & BUDDY_FLAG_SELF) != 0;
}

void Buddy::setPriority(BuddyPriority priority){
	switch(priority){
		case BUDDY_PRIORITY_LOW:
			flags &= ~BUDDY_FLAG_PRIORITY_HIGH;
			flags |= BUDDY_FLAG_PRIORITY_LOW;
			break;
		case BUDDY_PRIORITY_HIGH:
			flags &= ~BUDDY_FLAG_PRIORITY_LOW;
			flags |= BUDDY_FLAG_PRIORITY_HIGH;
			break;
		case BUDDY_PRIORITY_NORMAL:
			flags &= ~(BUDDY_FLAG_PRIORITY_LOW|BUDDY_FLAG_PRIORITY_HIGH);
			break;
	}
}
void Buddy::addToPrivacyList(BuddyPrivacyList list){
	switch(list){
		case BUDDY_PRIVACY_IGNORED:
			flags |= BUDDY_FLAG_IGNORED;
			break;
		case BUDDY_PRIVACY_VISIBLELIST:
			flags &= ~BUDDY_FLAG_INVISIBLELIST;
			flags |= BUDDY_FLAG_VISISBLELIST;
			break;
		case BUDDY_PRIVACY_INVISIBLELIST:
			flags &= ~BUDDY_FLAG_VISISBLELIST;
			flags |= BUDDY_FLAG_INVISIBLELIST;
			break;
		default:
			wxLogDebug(wxT("Buddy::addToPrivacyList: illegal argument"));
	}
}

void Buddy::removeFromPrivacyList(BuddyPrivacyList list){
	switch(list){
		case BUDDY_PRIVACY_IGNORED:
			flags &= ~BUDDY_FLAG_IGNORED;
			break;
		case BUDDY_PRIVACY_VISIBLELIST:
			flags &= ~BUDDY_FLAG_VISISBLELIST;
			break;
		case BUDDY_PRIVACY_INVISIBLELIST:
			flags &= ~BUDDY_FLAG_INVISIBLELIST;
			break;
		default:
			wxLogDebug(wxT("Buddy::removeFromPrivacyList: illegal argument"));
	}
}

void Buddy::setHasUnredMsg(bool unredMsg){
	if(unredMsg){
		flags |= BUDDY_FLAG_UNREAD_MSG;
	}else{
		flags &= ~BUDDY_FLAG_UNREAD_MSG;
	}
}
void Buddy::setHasAuthorisation(bool hasAuth){
	if(!hasAuth){
		flags |= BUDDY_FLAG_NO_AUTHORIZATION;
	}else{
		flags &= ~BUDDY_FLAG_NO_AUTHORIZATION;
	}
}
void Buddy::setIsInBuddylist(bool inList){
	if(!inList){
		flags |= BUDDY_FLAG_NOT_INLIST;
	}else{
		flags &= ~BUDDY_FLAG_NOT_INLIST;
	}
}

int Buddy::getFlags() const{
	return flags;
}

void Buddy::setExtendedInfo(const wxString & name,const  wxString & value){
	//wxLogDebug(wxT("%s setting %s=%s"), getName().c_str(), name.c_str(), value.c_str());
	Impp::exemplar()->getDatabase()->setStringValue(this,name,value);
}

wxString Buddy::getExtendedInfo(const wxString & name){
	return Impp::exemplar()->getDatabase()->getStringValue(this,name,wxEmptyString);
}

bool Buddy::getOnlineTime(wxDateTime & time){
	if(protData==NULL){
		return false;
	}
	return protData->getOnlineTime(time);
}

bool Buddy::getIdleTime(wxDateTime & time){
	if(protData==NULL){
		return false;
	}
	return protData->getIdleTime(time);
}

bool Buddy::getIp(wxString & ip){
	if(protData==NULL){
		return false;
	}
	return protData->getIp(ip);
}

}
